﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using UnityEngine;
using Random = UnityEngine.Random;
using Object = UnityEngine.Object;
using Debug = UnityEngine.Debug;
using System.Diagnostics;
using System.Text;

public class SvnOperation
{
    public static void ExeSvnShowLog()
    {
        string path = new DirectoryInfo("./Assets").FullName;
        // Debug.Log(path);
        Excute("TortoiseProc.exe", "/command:log /path:" + path, false, false, false);
    }
    public static void ExeSvnShowLog(string path)
    {
        // Debug.Log(path);
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        Excute("TortoiseProc.exe", "/command:log /path:" + path, false, false, false);
    }

    public static void ExeSvnCommitAssets()
    {
        string path = new DirectoryInfo("./Assets").FullName;
        // Debug.Log(path);
        Excute("TortoiseProc.exe", "/command:commit /path:" + path, false, false, false);
    }

    public static void ExeSvnCommitProjectSettings()
    {
        string path = new DirectoryInfo("./ProjectSettings").FullName;
        // Debug.Log(path);
        Excute("TortoiseProc.exe", "/command:commit /path:" + path, false, false, false);
    }

    public static void ExeSvnCommit()
    {
        string path = new DirectoryInfo("./").FullName;
        // Debug.Log(path);
        Excute("TortoiseProc.exe", "/command:commit /path:" + path, false, false, false);
    }

    public static void ExeSvnCommit(string path)
    {
        // Debug.Log(path);
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        Excute("TortoiseProc.exe", "/command:commit /path:" + path, false, false, false);
    }

    public static void ExeSvnCommitAll()
    {
        Excute("TortoiseProc.exe", "/command:commit /path:" + new DirectoryInfo("./../").FullName, false, false, false);
    }

    public static bool ExeSvnCommitAll(string path, string logMsg)
    {
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        string input = Excute("svn", "status " + path, true, true, true);
        Match match = Regex.Match(input, @"\? +(.+)", RegexOptions.Compiled);
        List<string> list = new List<string>();
        while (match.Success)
        {
            string str2 = match.Groups[1].Value.TrimEnd(new char[] { '\r', '\n' });
            if (str2.IndexOf("@") != -1)
            {
                str2 = str2 + "@";
            }
            list.Add('"' + str2 + '"');
            match = match.NextMatch();
        }
        if (list.Count > 0)
        {
            string str3 = Excute("svn", "add " + string.Join(" ", list.ToArray()), true, true, true);
            if (IsFail(str3))
            {
                Debug.LogError("svn添加失败\n" + str3);
                return false;
            }
            Debug.Log("添加文件：\n" + str3);
        }
        Match match2 = Regex.Match(input, @"\! +(.+)", RegexOptions.Compiled);
        List<string> list2 = new List<string>();
        while (match2.Success)
        {
            string str4 = match2.Groups[1].Value.TrimEnd(new char[] { '\r', '\n' });
            if (str4.IndexOf("@") != -1)
            {
                str4 = str4 + "@";
            }
            list2.Add('"' + str4 + '"');
            match2 = match2.NextMatch();
        }
        if (list2.Count > 0)
        {
            string str5 = Excute("svn", "delete " + string.Join(" ", list2.ToArray()), true, true, true);
            if (IsFail(str5))
            {
                Debug.LogError("svn删除失败\n" + str5);
                return false;
            }
            Debug.Log("删除文件：\n" + str5);
        }
        string result = Excute("svn", string.Format("commit {0} -m \"{1}\"", path, logMsg), true, true, true);
        Debug.Log("提交文件：\n" + result);
        if (IsFail(result))
        {
            Debug.LogError("svn提交失败\n" + result);
            return false;
        }
        return true;
    }

    public static void ExeSvnFullRevert(string path, bool waitForExit = false)
    {
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        Excute("TortoiseProc.exe", "/command:cleanup /noui /noprogressui /nodlg /revert /delunversioned /path:" + path, true, false, waitForExit);
    }

    public static void ExeSvnRevert(string path, bool waitForExit = false)
    {
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        Excute("svn", "revert -R " + path, true, false, waitForExit);
    }

    public static void ExeSvnUpdate()
    {
        string path = "/command:update /path:" + new DirectoryInfo("./").FullName;
        Excute("TortoiseProc.exe",path , false, false, false);
    }

    public static void ExeSvnUpdate(string path)
    {
        DirectoryInfo dic = new DirectoryInfo(path);
        path = dic.FullName;
        Excute("TortoiseProc.exe", "/command:update /path:" + path, false, false, false);
    }


    public static void ExeSvnUpdateAll()
    {
        Excute("TortoiseProc.exe", "/command:update /path:" + new DirectoryInfo("./../").FullName, false, false, false);
    }

    private static bool IsFail(string result)
    {
        if (result.IndexOf("failed") == -1)
        {
            return Regex.IsMatch(result, "svn: E");
        }
        return true;
    }

    public static string Excute(string exeName, string args, bool hide = false, bool redirect = false, bool waitForExit = false)
    {
        Process p = new Process();
        string str = Excute(p, exeName, args, hide, redirect, waitForExit);
        p.Dispose();
        return str;
    }

    public static string Excute(Process p, string exeName, string args, bool hide = false, bool redirect = false, bool waitForExit = false)
    {
        p.StartInfo.FileName = exeName;
        p.StartInfo.Arguments = args;
        if (hide || redirect)
        {
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.UseShellExecute = false;
        }
        string str = "";
        if (redirect)
        {
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.StandardOutputEncoding = Encoding.GetEncoding("GB2312");
        }
        try
        {
            p.Start();
        }
        catch (Exception exception)
        {
            Debug.LogException(exception);
        }
        if (redirect)
        {
            str = p.StandardOutput.ReadToEnd();
        }
        if (redirect || waitForExit)
        {
            p.WaitForExit();
        }
        return str;
    }
}

